﻿using System.Collections.Generic;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Application.IO;
using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Cms.Tests.Unit.Application.Admin.Presenters
{
    [TestClass]
    public class EditSitePresenterTests : BasePresenterTests
    {
        private Mock<IEditSiteView> _viewMock;
        private Administrator _admin;
        private AdministratorGroup _adminGroup;
        private AdministratorGroup _regularGroup;
        private Site _site;
        private IList<Site> _allSites;

        private void Prepare()
        {
            InitRepositoryFactoryMock();
            _viewMock = new Mock<IEditSiteView>();
            _viewMock.SetupAllProperties();
            _viewMock.SetupGet(m => m.AdministratorID).Returns(1);
            _viewMock.Setup(m => m.Localization).Returns("en-US");
            _viewMock.Setup(m => m.ContextTranslationFile).Returns("Admin/Translations/EditSite.xml");
            _admin = new Administrator() { ID = 1 };
            _adminGroup = new AdministratorGroup() { ID = 1 };
            _regularGroup = new AdministratorGroup();
            AdministratorRepositoryMock.Setup(m => m.GetAdministrator(1)).Returns(_admin);
            AdministratorRepositoryMock.Setup(m => m.GetGroup(1)).Returns(_adminGroup);
            _site = new Site() { ID = 1 };
            _allSites = new List<Site> { _site };
            SiteRepositoryMock.Setup(m => m.GetSite(1)).Returns(_site);
            SiteRepositoryMock.Setup(m => m.GetSites()).Returns(_allSites);
        }

        [TestMethod]
        public void Constructor_AdminHasAccess_Allowed()
        {
            Prepare();
            _admin.Group = _adminGroup;
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.RedirectToPermissionDeniedPage(), Times.Never());
        }

        [TestMethod]
        public void Constructor_AdminHasNoAccess_Denied()
        {
            Prepare();
            _admin.Group = _regularGroup;
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.RedirectToPermissionDeniedPage(), Times.Exactly(1));
        }

        [TestMethod]
        public void Initialize_InvalidSiteID_RedirectToBadRequestParameter()
        {
            Prepare();
            _viewMock.SetupGet(m => m.SiteID).Returns(0);
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Initialize();
            _viewMock.Verify(m => m.RedirectToBadRequestParameterPage(), Times.Exactly(1));
        }

        [TestMethod]
        public void Initialize_NewSite_ViewIsLeftBlank()
        {
            Prepare();
            _viewMock.SetupGet(m => m.SiteID).Returns(-1);
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Initialize();
            _viewMock.Verify(m => m.Domain, Times.Never());
            _viewMock.Verify(m => m.RootMediaFolder, Times.Never());
            _viewMock.Verify(m => m.SetLocales(It.IsAny<IList<Locale>>()), Times.Never());
            Assert.IsTrue(_viewMock.Object.Online);
        }

        [TestMethod]
        public void Initialize_EditSite_ViewIsUpdated()
        {
            Prepare();
            Locale defaultLocale = new Locale() { ID = 1 };
            _site.DefaultLocale = defaultLocale;
            _viewMock.SetupGet(m => m.SiteID).Returns(1);
            _site.Domain = "www.fredium.com";
            _site.RootMediaFolder = "media";
            _site.Online = true;
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Initialize();
            Assert.AreEqual(_site.Domain, _viewMock.Object.Domain);
            Assert.AreEqual(_site.RootMediaFolder, _viewMock.Object.RootMediaFolder);
            Assert.AreEqual(_site.Online, _viewMock.Object.Online);
        }

        [TestMethod]
        public void Save_EditSite_RootMediaFolderIsCreatedIfNotExists()
        {
            Prepare();
            _viewMock.SetupGet(m => m.SiteID).Returns(1);
            _viewMock.SetupGet(m => m.Domain).Returns("www.fredium.com");
            _viewMock.SetupGet(m => m.RootMediaFolder).Returns("media");
            _site.Domain = "www.fredium.com";
            _site.RootMediaFolder = "media";
            _adminGroup.Administrators.Add(_admin);
            EditSitePresenter presenter = new EditSitePresenter(_viewMock.Object, FactoryMock.Object);
            Mock<IDiskAccess> diskAccessMock = new Mock<IDiskAccess>();
            presenter.DiskAccess = diskAccessMock.Object;
            presenter.Save();
            diskAccessMock.Verify(m => m.CreateDirectory("media"), Times.Once());
        }
    }
}
